//
// Created by 30938 on 2022/8/27.
//
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

/*
 ios::out -> 写w
 iOS::app -> 追加写a
 ios::in -> 读r
 ios::binary -> 二进制
 * */


void test01() {
    ofstream ofs("../cpp0616/1.txt", ios::app);
    ofs << "hello world" << endl << "zhaosi" << endl;
    ofs.close();
}

void test02() {
    ifstream ifs("../cpp0616/1.txt");
    string str;
    ifs >> str;
    ifs.close();
    cout << str << endl;
}

class Student {
    friend ostream &operator<<(ostream &out, const Student &ins) {
        out << ins.name << " " << ins.age << " " << ins.phone << " " << ins.sex << endl;
        return out;
    }

public:
    Student(const string name, const string phone, const int age, const char sex) {
        this->phone = phone;
        this->sex = sex;
        this->name = name;
        this->age = age;
    }

private:
    string name;
    string phone;
    int age;
    char sex;
};


// 按行获取文件内容，并将
void test03() {
    ifstream ifs;
    ifs.open("../cpp0616/stulist.txt");
    vector<Student> arr;

    if (ifs.is_open()) {
        string name;
        string phone;
        int age;
        char sex;
        while (ifs >> name >> age >> phone >> sex) {
            arr.push_back(Student(name, phone, age, sex));
            // cout<<ifs.tellp()<<endl;
        }
        ifs.close();
    } else {
        cout << "文件不存在" << endl;
    }
    for (auto elem: arr) {
        cout << elem;
    }
}

void test04() {
    FILE *fp = fopen("D:\\cpp_study\\project\\cpp0616\\stulist.txt", "r");
    fseek(fp, 0, SEEK_END);
    uint64_t size = ftell(fp);
    cout << size << endl;
    fclose(fp);

    ifstream ifs("D:\\cpp_study\\project\\cpp0616\\stulist.txt");
    ifs.seekg(0, ios::end);
    auto size2 = ifs.tellg();
    cout << size2 << endl;
    ifs.close();
}

// 拷贝大型文件（500MB以上）
void test05() {
    ifstream ifs("E:\\SOFTWAER\\c++\\clion\\CLion-2021.3.4.exe", ios::binary);
    ofstream ofs("E:\\SOFTWAER\\c++\\clion\\CLion-2021.3.4.bp.exe", ios::binary);

    ifs.seekg(0, ios::end);
    streamsize totalSize = ifs.tellg();
    ifs.seekg(0, ios::beg);

    char buffer[1024 * 1024] = {0};
    while (!ifs.eof()) {
        ifs.read(buffer, sizeof(buffer));
        auto len = ifs.gcount();
        ofs.write(buffer, len);
        ofs.flush();
        streamsize currSize = ofs.tellp();
        printf("总大小%.2fMB,已复制%.2fMB,当前进度%.2f%%\n", \
        (float) totalSize / 1024 / 1024, (float) currSize / 1024 / 1024, (float) currSize / totalSize * 100);
    }
    ifs.close();
    ofs.close();
}

// 断点续传
void test06() {
    ifstream ifs("E:\\SOFTWAER\\c++\\clion\\CLion-2021.3.4.exe", ios::binary);
    ofstream ofs("E:\\SOFTWAER\\c++\\clion\\CLion-2021.3.4.bp.exe", \
    ios::binary | ios::app);
    streamsize copiedSize = 0;

    if (ofs.is_open()) {
        ofs.seekp(0, ios::end);
        copiedSize = ofs.tellp();  // 已考备
    }

    ifs.seekg(0, ios::end);
    streamsize totalSize = ifs.tellg();  // 文件总大小tellg（）

    if (copiedSize >= totalSize) {
        return;
    }
    ifs.seekg(copiedSize, ios::beg); // 从已考备的字节往下读
    char buffer[4096] = {0};
    while (!ifs.eof()) {
        ifs.read(buffer, sizeof(buffer));
        auto len = ifs.gcount();
        ofs.write(buffer, len);
        ofs.flush();
        streamsize currSize = ofs.tellp();
        printf("总大小%.2fMB,已复制%.2fMB,当前进度%.2f%%\n", \
        (float) totalSize / 1024 / 1024, (float) currSize / 1024 / 1024, (float) currSize / totalSize * 100);
    }
    ifs.close();
    ofs.close();
}

int main() {
    test06();
    //test05();
    // test04();
    // test03();
    // test02();
    // test01();
    return 0;
}
